home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / PROLOG / HUMBOLT / HUMBOLTS / _files / _humboltsr / EVAL._c < prev    next >
Text File  |  1990-12-08  |  28KB  |  956 lines

  1. /***************************************************
  2. ****************************************************
  3. **                                                **
  4. **  HU-Prolog     Portable Interpreter System     **
  5. **                                                **
  6. **  Release 1.62   January  1990                  **
  7. **                                                **
  8. **  Authors:      C.Horn, M.Dziadzka, M.Horn      **
  9. **                                                **
  10. **  (C) 1989      Humboldt-University             **
  11. **                Department of Mathematics       **
  12. **                GDR 1086 Berlin, P.O.Box 1297   **
  13. **                                                **
  14. ****************************************************
  15. ***************************************************/
  16.  
  17. #include <setjmp.h>
  18.  
  19. #include "systems.h"
  20. #include "types.h"
  21. #include "errors.h"
  22. #include "atoms.h"
  23. #include "files.h"
  24.  
  25. /*
  26.  
  27. EVALUABLE PREDICATES
  28.  
  29. */
  30.  
  31.  
  32. IMPORT int BCT ;               /* from execute.c       */
  33. IMPORT ATOM GetAtom();          /* from atomtable.c     */
  34. IMPORT boolean INTRES();        /* from unify.c         */
  35. IMPORT ENV NEWENV();            /* from unify.c         */
  36. IMPORT void KILLSTACKS();       /* from unify.c         */
  37. IMPORT boolean DOFASSIGN();
  38. IMPORT void DOABOLISH();        /* from retract.c       */
  39. IMPORT boolean FERRORFLAG;      /* from files.c         */
  40. #ifdef ARCHY
  41. IMPORT boolean SYNCLFLAG;       /* from io.c */
  42. #endif
  43. IMPORT boolean ECHOFLAG,HALTFLAG,OCHECK;
  44. IMPORT boolean WARNFLAG,TRACING,SPYTRACE;
  45. IMPORT boolean aSYSMODE,REDUCEFLAG;
  46. IMPORT boolean ENAB_INTR;
  47. IMPORT int SPYING;
  48. IMPORT ENV E;
  49. IMPORT ENV CHOICEPOINT;  /* from execute.c       */
  50. IMPORT void DOVERSION();
  51. IMPORT void DOOP();             /* from atomtabl.c      */
  52. IMPORT void ARGERROR(),ERROR(),ABORT(),SYSTEMERROR(); /* from linebufffer.c */
  53. IMPORT void REGET();
  54. IMPORT file OpenFile();        /* from files.c */
  55. IMPORT void CloseFile();     
  56. IMPORT void LISTOUT();         /* from writeout.c */
  57. IMPORT void DOPUT(),DOCLS();   /* from inout.c */
  58. IMPORT void DOGOTOXY(),DOTAB(),DOSKIP();
  59. IMPORT ENV TRACE_GOON;           /* from writeout.c      */
  60. IMPORT void DOPRIVATE(),DOHIDE();
  61. IMPORT void DOASSERT(),DOASSA();          /* from assert.c        */
  62. IMPORT boolean DOANCESTORS(),DOAPPEND(),DOMEMBER();
  63. IMPORT boolean DOSAVE();
  64. IMPORT void STARTATOM(),ATOMCHAR();
  65. IMPORT string NEWATOM;
  66. IMPORT boolean EVENT;
  67. IMPORT jmp_buf error_label;              /* from prolog.c        */
  68. IMPORT int ERRORFLAG;           /* the current error no if any */
  69. IMPORT boolean RES;
  70. IMPORT ATOM LOOKUP(),LOOKATOM(),copyatom(),atom();
  71. IMPORT boolean CallUser();               /* from usereval.c */
  72. IMPORT boolean DOCONSULT();
  73. IMPORT boolean xWINDOW_ON;
  74. IMPORT void wq();
  75. IMPORT TERM READIN();
  76. IMPORT boolean DOTIME(),DOTIMER(),DOGET0(),DOGET(),DOASK();
  77. IMPORT boolean DOSEE(), DOSEEN(), DOTELL(),DOOPEN(),DOCLOSE();
  78. IMPORT boolean DOREAD();
  79. IMPORT boolean LINEENDED(),FILEENDED(),DONAME(),DOIS();
  80. IMPORT boolean DOACOMP(),DODASS(),DOREDUCE(),DOCLAUSE();
  81. IMPORT boolean DORETRACT(),DOENSURE(),DOSEEK();
  82. IMPORT boolean DOPEEK(),DOPOKE();
  83. IMPORT boolean islist();
  84. IMPORT boolean UserAbort;
  85. IMPORT void ws(),WRITEOUT(),DISPLAY(),LONG_JMP();
  86. IMPORT boolean UNIFY();
  87. IMPORT int INTVALUE();
  88. #if WINDOWS
  89. IMPORT char t_rc();
  90. #endif
  91. #if DBASE3
  92. IMPORT boolean DOOPENDBF(),DOCLOSEDBF(),DOREADDBF();
  93. IMPORT boolean DOWRITEDBF(),DOSEEKDBF(),DOERASEDBF();
  94. #endif
  95. IMPORT void setinfile(),setoutfile(),getinfile(),DOSTATS(),getoutfile();
  96. IMPORT int ARGC;
  97. IMPORT char **ARGV;
  98. IMPORT TERM HEAPTOP,GLOTOP;
  99. IMPORT ATOM ATOMSTOP,ATOMHTOP;
  100. IMPORT ENV ENVTOP;
  101. IMPORT TRAIL TRAILEND;
  102. IMPORT int RETURN_CODE;
  103.  
  104. #if SYMBOLARITH
  105. IMPORT TERM SUBSTITUTION();
  106. #endif
  107.  
  108. #if !CPM
  109. #if !RISCOS
  110. IMPORT putenv();
  111. #endif
  112. IMPORT char *getenv();
  113. IMPORT boolean call_system();            /* from systems.c       */
  114. #endif
  115.  
  116. TERM A0,A1,A2,A3;            /* global Arguments for all evaluable p. */
  117.  
  118. #define set_spytrace()   {if(SPYTRACE= (SPYING || TRACING))EVENT=true;}
  119.  
  120. GLOBAL void CHECKATOM(register TERM A)
  121. { if(name(A)<NORMATOM || arity(name(A))) ARGERROR();
  122. }
  123.  
  124. GLOBAL boolean isatom(register TERM T)
  125. { return name(T)>=NORMATOM && arity(name(T))==0; }
  126.  
  127. GLOBAL void TESTATOM(register ATOM A, register TERM T)
  128. { if(name(T)!=A) ARGERROR(); }
  129.  
  130. #if !CPM
  131. LOCAL boolean DOGETENV(void)
  132. {
  133.     register char *envp;
  134.     CHECKATOM(A1);
  135.     if(envp=getenv(tempcopy(name(A1))))
  136.     return UNI(A0,mkatom(LOOKUP(envp,0,false)));
  137.     else return false;
  138. }
  139. #if !P8000 && !RISCOS
  140. LOCAL void DOPUTENV(void)
  141. {
  142.     if(isatom(A0) && isatom(A1))
  143.     {
  144.         register char *s;
  145.         STARTATOM();
  146.         s=tempcopy(name(A0)); while(*s)ATOMCHAR(*s++);
  147.         ATOMCHAR('=');
  148.         s=tempcopy(name(A1)); while(*s)ATOMCHAR(*s++);
  149.         ATOMCHAR('\0');
  150.         putenv(NEWATOM); /* -- problematisch -- md */
  151.     }
  152.     else ARGERROR();
  153. }
  154. #endif
  155. #endif
  156.  
  157.  
  158. LOCAL boolean DODICT(boolean SYSTEM)
  159.     register ATOM A=nil_atom;
  160.     register TERM T=nil_term;
  161.     for (A=GetAtom(nil_atom);non_nil_atom(A);A=GetAtom(A))
  162.     {   
  163.         register TERM Q; 
  164.         if((system(A) && !SYSTEM) || (SYSTEM && !system(A)))
  165.             continue;
  166.         Q=mk2sons(LOOKATOM(A,0),nil_term,INTT,(TERM)arity(A));
  167.         if(non_nil_term(T)) T=mk2sons(DIVIDE_2,Q,CONS_2,T);
  168.         else T=mk2sons(DIVIDE_2,Q,NIL_0,nil_term);
  169.     }
  170.     if(non_nil_term(T)) return UNI(A0,mkfunc(CONS_2,T));
  171.     return UNI(A0,mkatom(NIL_0));
  172. }
  173.  
  174. LOCAL int compare( TERM A,  TERM B, int DEPTH)
  175.     int N;
  176.     ATOM AA,BB;
  177. #if REALARITH
  178.     REAL R;
  179. #endif
  180. #if LONGARITH
  181.     LONG L;
  182. #endif
  183.     int i,aar;
  184. #if REALARITH
  185. #define realret(expr) { R=expr; if(R < (REAL)0) return -1;\
  186.                                 else return  (R > (REAL)0); \
  187.                        }
  188. #endif   
  189. #if LONGARITH
  190. #define longret(expr) { L=expr; if(L < (LONG)0) return -1;\
  191.                                 else return  (L > (LONG)0); \
  192.                        }   
  193. #endif
  194.     if(DEPTH <=0) ABORT(DEPTHE);
  195.     deref(A); deref(B);
  196.     if((AA=name(A))==UNBOUNDT)
  197.         if(name(B)==UNBOUNDT) 
  198.             return 0;
  199.         else return -1;
  200.     else if(AA >=NORMATOM)
  201.     { STRING AIDX,BIDX; char CA,CB;
  202.         if((BB=name(B)) < NORMATOM) return 1;
  203.         AIDX=longstring(AA); BIDX=longstring(BB);
  204.         for(;;) 
  205.          { CA=repchar(AIDX); CB=repchar(BIDX);
  206.            if(CA || CB)
  207.              if(CA==CB) { AIDX++; BIDX++; continue; }
  208.              else return CA-CB;
  209.            else break;
  210.          }   
  211.         aar=arity(name(A)); /*==arity(name(B)) */
  212.         A=son(A); B=son(B);
  213.         N = 0;
  214.         for(i=0;i < aar && ((N=compare(A,B,DEPTH-1))==0) ; i++)
  215.         { 
  216.             next_br(A);next_br(B);
  217.         }
  218.         if(N) return N;
  219.         if(A) 
  220.             if(B) return 0; 
  221.             else return 1;
  222.         else 
  223.             if(B) return -1; 
  224.             else return 0;
  225.     }
  226.     else if(AA==INTT )
  227.     {
  228.         if((BB=name(B))==UNBOUNDT) return 1;
  229.         if(BB==INTT) return ival(A)-ival(B);
  230. #if LONGARITH
  231.         else if(BB==LONGT){longret(ival(A)-longval(B));}
  232. #endif
  233. #if REALARITH
  234.         else if(BB==REALT){realret(ival(A)-realval(B));} 
  235. #endif
  236.         else return -1;
  237.     }
  238. #if LONGARITH
  239.     else if(AA==LONGT)
  240.     {
  241.         if((BB=name(B))==UNBOUNDT) return 1;
  242.         else if(BB==INTT) {longret(longval(A)-ival(B));}
  243.         else if(BB==LONGT){longret(longval(A)-longval(B));}
  244. #if REALARITH
  245.         else if(BB==REALT){realret(longval(A)-realval(B));} 
  246. #endif
  247.         else return -1;
  248.     }
  249. #endif
  250. #if REALARITH
  251.     else if(AA==REALT )
  252.     {
  253.         if((BB=name(B))==UNBOUNDT) return 1;
  254.         else if(BB==INTT) {realret(realval(A)-ival(B));}
  255. #if LONGARITH
  256.         else if(BB==LONGT){realret(realval(A)-longval(B));}
  257. #endif
  258.         else if(BB==REALT){realret(realval(A)-realval(B));} 
  259.         else return -1;
  260.     }
  261. #endif
  262.     else SYSTEMERROR("compare");        
  263. #if REALARITH
  264. #undef realret
  265. #endif
  266. #undef longret
  267.   return 0; /* never reached, keeps lint silent */
  268. }
  269.  
  270.  
  271. LOCAL boolean DOFUNCTOR (void)
  272.     TERM  X, Y;
  273.     ATOM A;
  274.     int  I, M;
  275.   
  276.     A=name(A0); 
  277.     if(is_number(A)) 
  278.             return UNI(A0,A1) && INTRES(A2,0);
  279.     if(A==UNBOUNDT)
  280.       { M=INTVALUE(A2);
  281.         if(isatom(A1) && M>=0)
  282.           { X=Y=stackterms(M);
  283.             for(I=0;I<M;I++)
  284.               { name(X)=UNBOUNDT; son(X)=nil_term; next_br(X);}
  285.             return UNI(A0,mkfunc(LOOKATOM(name(A1),M),Y)); 
  286.           }
  287.         if(name(A1)==INTT && M==0) 
  288.             return INTRES(A0,ival(A1));
  289.         if((name(A1)==REALT || name(A1)==LONGT) && M==0)
  290.             return UNI(A0,A1);
  291.         ARGERROR();
  292.       }     
  293.     return INTRES(A2,(int)arity(A)) && UNI(A1,mkatom(LOOKATOM(A,0)));
  294. }
  295.  
  296. LOCAL boolean DOARG (void)
  297.     register TERM  X;
  298.     register int  I, N;
  299.     
  300.     if(name(A0)!=INTT || name(A1)< NORMATOM ) ABORT(ARGE);
  301.     N= (int)ival(A0);
  302.     if(N<1 || N> arity(name(A1))) 
  303.         ABORT(ARGE);
  304.     X=son(A1);
  305.     for(I=2; I<=N; ++I) next_br(X);
  306.     return UNI(A2,X);
  307. }
  308.  
  309. LOCAL int LISTATOM(ATOM A)
  310.     register CLAUSE CL; register TERM X; int N=0;
  311.   
  312.     if(class(A) !=NORMP) return 0;
  313.     if((system(A) || hide(A) || private(A)) && !DEBUGFLAG) return 0;
  314.     if(A==REPEAT_0) return 0;
  315. /*    if(*tempcopy(A)== '$' && !DEBUGFLAG) return 0; */
  316.     for(CL=clause(A);non_nil_clause(CL);CL=nextcl(CL))
  317.     { 
  318.         LISTOUT(head(CL));
  319.         if(name(X=body(CL)))
  320.         {   register notfirst =0;
  321.             ws(":-");
  322.             for(;;) 
  323.             { 
  324.                 while(name(X)==GOTO_1) X=son(X);
  325.                 if(name(X)==nil_atom) break;
  326.                 if(notfirst++) ws(",");
  327.                 ws("\n    ");LISTOUT(X);next_br(X);
  328.                 if(UserAbort) return(N);
  329.             }
  330.         }
  331.         ws(".\n");
  332.         N++;
  333.         if(UserAbort) return(N);
  334.     }
  335.     return N;
  336. }
  337.  
  338. LOCAL void DOLISTING(void)
  339.     ATOM A,AA;
  340.     int N=0,i;
  341.   
  342.     if(isatom(A0))
  343.     {
  344.         if(name(A0)!=ALL_0 )
  345.         {   A=name(A0);
  346.             for(i=0;i<MAXARITY;++i)
  347.             { AA=LOOKATOM(A,-i);
  348.               if(non_nil_atom(AA) && isheapatom(AA)) N +=LISTATOM(AA);
  349.             }
  350.             if(WARNFLAG && N==0 )
  351.             { ws("WARNING: no clause for relation ");
  352.               wq(name(A0)); ws("\n"); 
  353.             }
  354.         }
  355.         else 
  356.         { /* name(A0)==ALL_0 */
  357.           for(A=GetAtom(nil_atom);non_nil_atom(A);A=GetAtom(A)) 
  358.             N+=LISTATOM(A); 
  359.         }
  360.     }
  361.     else 
  362.     { 
  363.         /* ! isatom(A0) */
  364.         if(non_nil_atom(A=atom(A0))) 
  365.             if(non_nil_atom(A) && isheapatom(A)) N+=LISTATOM(A); 
  366.         if(WARNFLAG && N==0)
  367.         {
  368.             ws("WARNING: no clause for relation ");
  369.             wq(A);ws("/");wi(arity(A)); ws("\n"); 
  370.         } 
  371.     } 
  372. }
  373.  
  374.  
  375. LOCAL void DOSPY(boolean SPYMODE)
  376.     ATOM A;
  377.     int i;
  378.     if(isatom(A0)) 
  379.         if(name(A0) !=ALL_0)
  380.             for(i=0;i<=MAXARITY;i++)
  381.             {
  382.                 A=LOOKATOM(name(A0),-i);
  383.                 if(non_nil_atom(A)) 
  384.                 {
  385.                     A=copyatom(A);
  386.                     if(!spy(A) && SPYMODE) SPYING++;
  387.                     if(spy(A) && !SPYMODE) SPYING--;
  388.                     if(SPYMODE) setspy(A); else setnotspy(A);
  389.                 }
  390.             }
  391.         else /* name(A0)==ALL_0 */
  392.         {
  393.             for(A=GetAtom(nil_atom);non_nil_atom(A);A=GetAtom(A))
  394.             {
  395.                 if(!spy(A) && SPYMODE) SPYING++;
  396.                 if(spy(A) && !SPYMODE) SPYING--;
  397.                 if(SPYMODE) setspy(A); else setnotspy(A);
  398.             }
  399.         }
  400.     else
  401.     { 
  402.         A=atom(A0); 
  403.         if(WARNFLAG && clause(A)==nil_clause) 
  404.         {       
  405.             ws("WARNING: no clause for relation "); 
  406.             wq(A); ws("/"); wi(arity(A));
  407.         }
  408.         A=copyatom(A);  
  409.         if(!spy(A) && SPYMODE) SPYING++;
  410.         if(spy(A) && !SPYMODE) SPYING--;
  411.         if(SPYMODE) setspy(A); else setnotspy(A);
  412.     }
  413.     set_spytrace();
  414. }
  415.  
  416.  
  417. GLOBAL boolean DOEQUAL(register TERM X0, register TERM X1, 
  418.                        REGISTER int DEPTH)
  419. {   register int i,aar;
  420.     register ATOM A;
  421.  
  422.     if(DEPTH <=0) ABORT(DEPTHE);
  423.     deref(X0); deref(X1);
  424.     if((A=name(X1))!=name(X0)) return false;
  425.     if(A==INTT) return ival(X0)==ival(X1);
  426.     if(A==UNBOUNDT) return X0==X1;
  427.     aar=arity(A); 
  428.     for(i=0,X1=son(X1),X0=son(X0);i<aar;i++,next_br(X1),next_br(X0))
  429.       if(! DOEQUAL(X0,X1,DEPTH-1)) return false;
  430.     return true;
  431. }
  432.  
  433. GLOBAL boolean ground(register TERM ARG, register int DEPTH)
  434. {   register int aar;
  435.     register ATOM A;
  436.     deref(ARG);
  437.     if(DEPTH <=0) ABORT(DEPTHE);
  438.     if((A=name(ARG))==UNBOUNDT) return false;
  439.     if(A<NORMATOM)  return true;
  440.     aar=arity(A);
  441.     ARG=son(ARG);
  442.     while(aar-- > 0)
  443.     {
  444.         if(! ground(ARG,DEPTH-1)) return false;
  445.         next_br(ARG);
  446.     }
  447.     return true;
  448. }
  449.  
  450. LOCAL boolean DOUNIV(void)
  451. {
  452.     ATOM A;
  453.     TERM X,Y,T;
  454.     int ARITY;
  455.     A=name(A0); 
  456.     if(A==UNBOUNDT)
  457.        {  for(T=A1,ARITY= -1; name(T)==CONS_2; ARITY++) T=arg2(T); 
  458.           if(name(T)!=NIL_0 || ARITY<0) ARGERROR();
  459.           if(ARITY==0) return UNI(A0,son(A1));
  460.           T=arg1(A1);
  461.           CHECKATOM(T);
  462.           Y=mkfunc(LOOKATOM(name(T),ARITY),stackterms(ARITY));
  463.           X=son(Y); T=arg2(A1);
  464.           while(ARITY--> 0)
  465.            { name(X)=UNBOUNDT; UNI(X,son(T));next_br(X); T=arg2(T); }
  466.           return UNI(Y,A0);
  467.        }
  468.     if(A<NORMATOM)
  469.       return UNI(A1,mkfunc(CONS_2,mk2sons(A,son(A0),NIL_0,nil_term)));
  470.     /* default */ 
  471.     X=Y=mkfunc(CONS_2,mk2sons(LOOKATOM(A,0),nil_term,NIL_0,nil_term));
  472.     ARITY=arity(A);
  473.     T=son(A0);
  474.     while(ARITY-->0)
  475.        { Y=br(son(Y)); 
  476.          name(Y)=CONS_2; son(Y)=mk2sons(UNBOUNDT,nil_term,NIL_0,nil_term);
  477.          UNI(son(Y),T);
  478.          next_br(T);
  479.        }
  480.     return UNI(X,A1);
  481. }  /* univ */
  482.  
  483. LOCAL boolean DOSORT(boolean delete)
  484. {
  485.     register TERM T,TT,S;
  486.     REGISTER TERM Res;
  487.     register int c;
  488.     if(!islist(A0,false)) ARGERROR();
  489.     Res=mkatom(NIL_0);
  490.     S=A0;
  491.     while(name(S)==CONS_2)
  492.     {   /* insert arg1(S) */
  493.         T=arg1(S);S=arg2(S);
  494.         TT=Res; c=1; /* set c to a value !=0 ! */
  495.         while(name(TT)==CONS_2 && (c=compare(arg1(TT),T,MAXDEPTH)) < 0)
  496.             TT=arg2(TT);
  497.         if(delete && c==0) continue;
  498.         /*
  499.         Temp=mk2sons(UNBOUNDT,nil_term,name(TT),son(TT));
  500.         name(TT)=CONS_2;
  501.         son(TT)=Temp;
  502.         UNI(Temp,T);
  503.         */
  504.         son(TT)=mk2sons(name(T),son(T),name(TT),son(TT));
  505.         name(TT)=CONS_2;
  506.     }
  507.     return UNI(A1,Res);
  508. }
  509.  
  510. /*
  511. **
  512. **  Flaghandling  on/off
  513. **
  514. */
  515.  
  516. LOCAL void SetFlag(boolean *FLAG)
  517. { ATOM A;
  518.   A=name(A0);
  519.   if(A==ON_0) *FLAG=true;
  520.   else if(A==OFF_0) *FLAG=false;
  521.     else if(A==UNBOUNDT)   
  522.               if(*FLAG)  UNI(A0,mkatom(ON_0));
  523.               else UNI(A0,mkatom(OFF_0));
  524.       else ARGERROR();
  525. }
  526.  
  527. LOCAL boolean DOCURATOM(boolean pred)
  528. /* current_predicate */
  529. {
  530.     ATOM A;
  531.     TERM T;
  532.     ENV NE,OC;
  533.  
  534.     OC=CHOICEPOINT;
  535.     if (!BCT) A=nil_atom; else A=(ATOM)BCT;
  536.     while(non_nil_atom(A=GetAtom(A)))
  537.     {
  538.         BCT=(int)A;
  539.         if(pred && (class(A) !=NORMP ||  clause(A)==nil_clause ||
  540.                      system(A))) continue;
  541.         NE=NEWENV(0);CHOICEPOINT=NE;
  542.         T=mk2sons(LOOKATOM(A,0),nil_term,INTT,(TERM)arity(A));
  543.         if(UNI(mkfunc(DIVIDE_2,T),A0))
  544.         { 
  545.             CHOICEPOINT=OC; return true; 
  546.         }
  547.         KILLSTACKS(NE);
  548.     }
  549.     return false;
  550. }
  551.  
  552.  
  553. LOCAL boolean DOCUROP(void)
  554. {
  555.     ATOM A,P;
  556.     ENV NE,OC;
  557.  
  558.     OC=CHOICEPOINT;
  559.     if (!BCT) A=nil_atom; else A=(ATOM)BCT;
  560.     while(non_nil_atom(A=GetAtom(A)))
  561.     {
  562.         switch(oclass(A))
  563.         {
  564.             case XFO:   P=XF_0;  break;
  565.             case FXO:   P=FX_0;  break;
  566.             case XFXO:  P=XFX_0; break;
  567.             case YFO:   P=YF_0;  break;
  568.             case FYO:   P=FY_0;  break;
  569.             case XFYO:  P=XFY_0; break;
  570.             case YFXO:  P=YFX_0; break;
  571.             default:    continue;
  572.         }
  573.         BCT=(int)A;
  574.         NE=NEWENV(0);CHOICEPOINT=NE;
  575.         if(   UNI(A0,mkint(oprec(A))) &&
  576.               UNI(A1,mkatom(P))   &&
  577.               UNI(A2,mkatom(LOOKATOM(A,0)))
  578.           )
  579.         { CHOICEPOINT=OC; return true; }
  580.         KILLSTACKS(NE);
  581.     }
  582.     return false;
  583. }
  584.  
  585. LOCAL void copy(register char *s)
  586. {
  587.     while(*s)
  588.         ATOMCHAR(*s++);
  589.     ATOMCHAR(' ');
  590. }
  591.  
  592. #if !CPM
  593. LOCAL boolean DOSYSTEM(void)
  594. {
  595.     TERM T;
  596.     ATOM A;
  597.  
  598.     STARTATOM(); /* init NEWATOM */
  599.     while(name(A0)==CONS_2)
  600.     {
  601.         T=arg1(A0); A=name(T); A0=arg2(A0);
  602.         if(A==INTT) copy(itoa(ival(T)));
  603. #if LONGARITH
  604.         else if(A==LONGT) copy(ltoa(longval(T)));
  605. #endif
  606. #if REALARITH
  607.         else if(A==REALT) copy(ftoa(realval(T)));
  608. #endif
  609.         else { CHECKATOM(T); copy(tempcopy(name(T))); }
  610.     }
  611.     TESTATOM(NIL_0,A0);
  612.     ATOMCHAR('\0'); /* terminate NEWATOM */
  613.     return call_system(NEWATOM);
  614. }
  615. #endif
  616.     
  617. boolean setval(int *x)
  618. {
  619.     if(name(A0)==UNBOUNDT) return INTRES(A0,*x);
  620.     if(name(A0)==INTT){*x=ival(A0); return true;}
  621.     ARGERROR();
  622.  
  623. }
  624.  
  625. LOCAL void copy_error_label(int *from, int *to)
  626. {   int size=sizeof(jmp_buf)/sizeof(int); 
  627.     while(size-- > 0) *to++= *from++;
  628. }
  629.  
  630.  
  631. TERM CALLX;
  632. ENV CALLXENV;
  633.  
  634. void CALLEVALPRED (TERM X, ENV ENVP)
  635.     ATOM NAME;
  636.     int  A;
  637.     auto jmp_buf old_error_label;
  638.     CALLX=X; CALLXENV=ENVP;
  639.     RES=true;
  640.     copy_error_label(error_label,old_error_label);
  641.     setjmp(error_label);
  642.     if(ERRORFLAG) { RES=false; goto exit; }
  643.  
  644.     E=ENVP; BE=base(ENVP);
  645.     deref(X);
  646.     NAME=name(X);
  647.     A=arity(NAME); 
  648.     X=son(X);
  649.     if(1<=A) 
  650.     { A0=X; deref(A0); next_br(X); 
  651.       if(2<=A) 
  652.       { A1=X; deref(A1); next_br(X); 
  653.         if(3<=A) 
  654.         { A2=X; deref(A2); next_br(X); 
  655.           if(4<=A) 
  656.           { A3=X; deref(A3);  
  657.             if (4<A) SYSTEMERROR("CALLEVALPRED.0");
  658.           }
  659.         }
  660.       }
  661.     }
  662.  
  663.     switch (NAME) 
  664.     { 
  665. #if !CPM
  666.     /* date/time handling */
  667.     case TIME_3:        
  668.     case DATE_3:       
  669.     case WEEKDAY_1:     RES=DOTIME(NAME); break;
  670.     case TIMER_1:       RES=DOTIMER(); break;
  671. #endif
  672.  
  673.     /* input/output predicates */
  674.     case OP_3:           DOOP();break;
  675.  
  676.     case READ_1:        RES=UNI(READIN(),A0); break;
  677.     case READ_2:        RES=DOREAD();break;
  678.     case WRITE_1:       WRITEOUT(A0,false); break;
  679.     case WRITEQ_1:      WRITEOUT(A0,true); break;
  680.     case DISPLAY_1:     DISPLAY(A0);break;
  681.     case GET0_1:        RES=DOGET0();break;
  682.     case GET_1:         RES=DOGET();break;
  683.     case UNGET_0:       REGET();break;
  684.     case SKIP_1:        DOSKIP();break;
  685.     case PUT_1:         DOPUT();break;
  686.     case CLS_0:         DOCLS(); break;
  687.     case NL_0:          ws("\n"); break;
  688.     case TAB_1:         DOTAB();break;
  689.     case GOTOXY_2:      DOGOTOXY(); break; 
  690.     case ASK_1:         RES=DOASK();break;
  691.  
  692.     case TTYREAD_1:    
  693.     case TTYGET0_1:   
  694.     case TTYGET_1:   
  695.     case TTYSKIP_1: 
  696.     case TTYASK_1:      setinfile();
  697.                         switch(NAME)
  698.                         {
  699.                           case TTYREAD_1:  RES=UNI(READIN(),A0); break;
  700.                           case TTYGET0_1:  RES=DOGET0();break;
  701.                           case TTYGET_1:   RES=DOGET();break;
  702.                           case TTYSKIP_1:  DOSKIP();break;
  703.                           case TTYASK_1:   RES=DOASK();break;
  704.                         }
  705.                         getinfile();
  706.                         break;
  707.     case TTYWRITE_1:    
  708.     case TTYPUT_1:     
  709.     case TTYCLS_0:    
  710.     case TTYNL_0:    
  711.     case TTYTAB_1:  
  712.     case TTYGOTOXY_2:   setoutfile();
  713.                         switch(NAME)
  714.                         {
  715.                           case TTYWRITE_1:  WRITEOUT(A0,false); break;
  716.                           case TTYPUT_1:    DOPUT();break;
  717.                           case TTYCLS_0:    DOCLS(); break;
  718.                           case TTYNL_0:     ws("\n"); break;
  719.                           case TTYTAB_1:    DOTAB();break;
  720.                           case TTYGOTOXY_2: DOGOTOXY(); break; 
  721.                         }
  722.                         getoutfile();
  723.                         break;
  724.  
  725.     case EOLN_0:        RES=LINEENDED(); break;
  726.     case EOF_0:         RES=FILEENDED(); break;
  727.     case SEE_1:         RES=DOSEE();break;
  728.     case SEEING_1:      RES=UNI(A0,mkatom(FLOGNAME(inputfile))); break;
  729.     case SEEN_0:        RES=DOSEEN();break;
  730.                         /* CloseFile(inputfile);A0=mkatom(USER_0);
  731.                         RES=DOSEE();break; */
  732.     case TELL_1:        RES=DOTELL();break;
  733.     case TELLING_1:     RES=UNI(A0,mkatom(FLOGNAME(outputfile))); break;
  734.     case TOLD_0:        CloseFile(outputfile);A0=mkatom(USER_0);
  735.                         RES=DOTELL();break;
  736.     case OPEN_1:        RES=DOOPEN();break;
  737.     case CLOSE_1:       RES=DOCLOSE();break;
  738. #if !CPM
  739.     case SEEK_2:        RES=DOSEEK();break;
  740. #endif
  741.     case WGET0_1:       
  742. #if WINDOWS
  743.                         if(xWINDOW_ON) RES=INTRES(A0,t_rc());
  744.                         else 
  745. #endif
  746.                         RES=DOGET0(); break;
  747.     case aWINDOW_0:     RES=xWINDOW_ON;break;
  748.     case FILEE_0:       FERRORFLAG=true;break;
  749.     case NFILEE_0:      FERRORFLAG=false;break;
  750. #ifdef ARCHY
  751.     case SYNCLOSE_0:    SYNCLFLAG=true; break;
  752.     case NSYNCLOSE_0:   SYNCLFLAG=false;break;
  753. #endif
  754.     case FILEE_1:       SetFlag(&FERRORFLAG);break;
  755.     case CONSULT_1:     RES=DOCONSULT(false);break;
  756.     case RECONSULT_1:   RES=DOCONSULT(true);break;
  757.  
  758.     case FASSIGN_2:     RES=DOFASSIGN();break;
  759. #if !CPM
  760.     case SYSTEM_1:      RES=DOSYSTEM();break;
  761. #endif
  762.     case ARGC_1:        RES=INTRES(A0,ARGC);break;
  763.     case ARGV_2:        {
  764.                             int i;
  765.                             if((i=INTVALUE(A1))<0 || i >=ARGC) 
  766.                                 ERROR(ARGE);
  767.                             RES=UNI(A0,mkatom(LOOKUP(ARGV[i],0,false)));
  768.                         }
  769.                         break;
  770. #if UNIX
  771.     case OPSYS_1:       RES=UNI(A0,mkatom(LOOKUP("unix",0,false))); break;
  772. #endif
  773. #if RISCOS
  774.     case OPSYS_1:       RES=UNI(A0,mkatom(LOOKUP("riscos",0,false))); break;
  775. #endif
  776. #if MS_DOS
  777.     case OPSYS_1:       RES=UNI(A0,mkatom(LOOKUP("msdos",0,false))); break;
  778. #endif
  779. #if CPM
  780.     case OPSYS_1:       RES=UNI(A0,mkatom(LOOKUP("cpm",0,false))); break;
  781. #endif
  782. #if VMS
  783.     case OPSYS_1:       RES=UNI(A0,mkatom(LOOKUP("vms",0,false))); break;
  784. #endif
  785.     case RESTART_0:     ABORT(NOERROR);break;
  786.     case ABORT_0:       ABORT(ABORTE); break;
  787.     case END_0:         HALTFLAG=true; break;
  788.     case TRACE_1:       SetFlag(&TRACING);set_spytrace();TRACE_GOON=0;
  789.                         break;
  790.     case TRACE_0:       TRACING=true; set_spytrace();TRACE_GOON=0;
  791.                             break;
  792.     case NOTRACE_0:     TRACING=false; set_spytrace();TRACE_GOON=0;
  793.                         break;
  794.     case SPY_1:         DOSPY(true); TRACE_GOON=0; break;
  795.     case NOSPY_1:       DOSPY(false); TRACE_GOON=0;
  796.                         break;
  797.     case ECHO_1:        SetFlag(&ECHOFLAG); break;
  798.     case DEBUG_1:       SetFlag(&DEBUGFLAG); break;
  799.     case STATS_0:       DOSTATS(); break;
  800.     case aINTERRUPT_1:  SetFlag(&ENAB_INTR);
  801.                         if(ENAB_INTR && UserAbort)EVENT=true;
  802.                         break;
  803.     case SYSMODE_1:     SetFlag(&aSYSMODE);break;
  804.     case REDUCE_1:      SetFlag(&REDUCEFLAG);break;
  805. #if OCCUR_CHECK
  806.     case OCHECK_1:      SetFlag(&OCHECK);break;
  807. #endif
  808.     case WARN_1:        SetFlag(&WARNFLAG);break;
  809.     case EXIT_1:        RETURN_CODE=INTVALUE(A0);
  810.     case HALT_0:        LONG_JMP(999);break;
  811.     case SAVE_1:        DOSAVE();break;
  812.  
  813.     /* term manipulation */
  814.     case LIST_1:        RES=islist(A0,false);break;
  815.     case STRING_1:      RES=islist(A0,true);break;
  816.     case COMPOUND_1:    RES=name(A0) > NORMATOM && arity(name(A0));
  817.                             break;
  818. #if REALARITH
  819.     case REAL_1:        RES=name(A0)==REALT;break;
  820. #endif
  821.     case NUMBER_1:      RES=is_number(name(A0));break;
  822.     case ATOMIC_1:      RES=isatom(A0) || is_number(name(A0));break;
  823.     case NONVAR_1:      RES=name(A0)!=UNBOUNDT; break;
  824.     case SYS_1:         RES=system(atom(A0));break;
  825.     case CURATOM_1:     RES=DOCURATOM( false );break;
  826.     case CURPRED_1:     RES=DOCURATOM( true );break;
  827.     case CUROP_3:       RES=DOCUROP();break;
  828.     case NAME_2:        RES=DONAME();  break;
  829.     case FUNCTOR_3:     RES=DOFUNCTOR();  break;
  830.     case ARG_3:         RES=DOARG();  break;
  831.     case UNIV_2:        RES=DOUNIV();break;
  832.     case MEMBER_2:      RES=DOMEMBER(); break;
  833.     case APP_3:         RES=DOAPPEND(); break;
  834.     case SORT_2:        RES=DOSORT(false);break;
  835.     case SORT0_2:       RES=DOSORT(true);break;
  836.     case EQUAL_2:       RES=DOEQUAL(A0,A1,MAXDEPTH);break;
  837.     case NOEQUAL_2:     RES= !DOEQUAL(A0,A1,MAXDEPTH);break;
  838.     case INVAR_1:       RES= !ground(A0,MAXDEPTH);break;
  839.     case GROUND_1:      RES=ground(A0,MAXDEPTH);break;
  840.     case ALT_2:         RES=compare(A0,A1,MAXDEPTH)<0;break;
  841.     case ALE_2:         RES=compare(A0,A1,MAXDEPTH)<=0;break;
  842.     case AGT_2:         RES=compare(A0,A1,MAXDEPTH)>0;break;
  843.     case AGE_2:         RES=compare(A0,A1,MAXDEPTH)>=0;break;
  844.     case AEQ_2:         RES=compare(A0,A1,MAXDEPTH)==0;break;
  845.     case ANE_2:         RES=compare(A0,A1,MAXDEPTH)!=0;break;
  846.  
  847.     /* arithmetic operations, see arith.c */
  848.     case IS_2:          RES=DOIS(A0,A1);break;
  849.     case ACOMP_1:       RES=DOACOMP();break;
  850.     case DASSIGN_2:     RES=DODASS();break;
  851.     case REDUCE_2:      DOREDUCE(A0,A1,false); break; 
  852.  
  853.     /* database operations */
  854.     case DICT_1:        RES=DODICT(false); break;
  855.     case SDICT_1:       RES=DODICT(true); break;
  856.  
  857.     case ASSERTA_1:     DOASSA();break;
  858.     case ARROW_2:       A0=mkfunc(ARROW_2,
  859.                                     mk2sons(name(A0),son(A0), name(A1),son(A1)));
  860.     case ASSERT_1:
  861.     case ASSERTZ_1:     A2=mkatom(END_0);
  862.                         DOASSERT(false);break;
  863.     case DBASS_2:
  864.     case DBASSZ_2:      A2=mkatom(END_0);
  865.                         DOASSERT(true);break;
  866.     case DBASSA_2:      A2=mkint(0);
  867.                         /* no break */
  868.     case DBASS_3:       DOASSERT(true);break;
  869.     case LISTALL_0:     A0=mkatom(ALL_0);/* no break */
  870.     case LISTING_1:     DOLISTING(); break;
  871.     case CLAUSE_2:      RES=DOCLAUSE(false);break;
  872.     case CLAUSE_3:      RES=DOCLAUSE(true);break;
  873.     case RETRACT_1:     RES=DORETRACT(false,false);break;
  874.     case DBRET_2:       RES=DORETRACT(true,false);break;
  875.     case RETALL_1:      RES=DORETRACT(false,true);break; 
  876.     case ABOL_1:        DOABOLISH(1);break;
  877.     case ABOL_2:        DOABOLISH(2);break;
  878.     case VERSION_0:     DOVERSION(); break;
  879.     case PRIVATE_1:     DOPRIVATE();break;
  880.     case HIDE_1:        DOHIDE();break;
  881.     case ANCESTORS_1:   RES=DOANCESTORS();break;
  882.     case ENSURE_3:      RES=DOENSURE();break;
  883.  
  884. #if !CPM
  885.     case GETENV_2:      RES=DOGETENV();break;
  886. #if !P8000 && !RISCOS
  887.     case PUTENV_2:      DOPUTENV();break;
  888. #endif
  889. #endif
  890.  
  891. #if HELP
  892.     case HELP_0:        DOHELP(nil_term);break;
  893.     case HELP_1:        DOHELP(A0);break;
  894. #endif
  895.  
  896. #if DBASE3
  897.     case OPENDBF_2:     RES=DOOPENDBF(A0,A1);break;
  898.     case CLOSEDBF_1:    RES=DOCLOSEDBF(A0);break;
  899.     case READDBF_3:     RES=DOREADDBF(A0,A1,A2);break;
  900.     case WRITEDBF_3:    RES=DOWRITEDBF(A0,A1,A2);break;
  901.     case SEEKDBF_2:     RES=DOSEEKDBF(A0,A1);break;
  902.     case ERASEDBF_2:    RES=DOERASEDBF(A0,A1);break;
  903. #endif
  904.  
  905. #if HACKY
  906.     case iCHOICEP_1:    RES=setval(&CHOICEPOINT);break;
  907.     case iSTACKT_1:     RES=setval(&GLOTOP);break;
  908.     case iHEAPT_1:      RES=setval(&HEAPTOP);break;
  909.     case iASTACKT_1:    RES=setval(&ATOMSTOP);break;
  910.     case iAHEAPT_1:     RES=setval(&ATOMHTOP);break;
  911.     case iENV_1:        RES=setval(&ENVTOP);break;
  912.     case iTRAIL_1:      RES=setval(&TRAILEND);break;
  913.     case iNROFCALLS_2:  RES=INTRES(A0,nrofcalls(atom(A1)));break;
  914. #endif
  915.  
  916. #if SYMBOLARITH
  917.     case SUBST_4:       RES=UNI(A0,SUBSTITUTION(A1,A2,A3)); break;
  918. #endif
  919.  
  920. #if CPM
  921.     case BDOS_3:        RES=INTRES(A2,
  922.                          bdos(INTVALUE(A0),INTVALUE(A1))); break;
  923. #endif
  924.  
  925. #if CPM || HACKY
  926.     case PEEK_3:        RES=DOPEEK(); break;
  927.     case POKE_2:        RES=DOPOKE(); break;
  928. #endif
  929.  
  930.     default:             
  931. #if USER
  932.           RES=CallUser(CALLX);break;
  933. #endif
  934. #if !USER
  935.           ws("\007sorry, this predicate is reserved, ");
  936.           ws("but not yet implemented\n");
  937.           ERROR(CALLE);
  938. #endif
  939.   }
  940.   CALLX=nil_term;
  941. exit:
  942.   copy_error_label(old_error_label,error_label);
  943.   return;
  944.  
  945. }
  946.  
  947.  
  948.